package com.jxt.app.util;

import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
import java.util.Timer;
import java.util.TimerTask;

import javax.sql.DataSource;

import org.apache.log4j.Logger;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.dao.Sqls;
import org.nutz.dao.entity.Entity;
import org.nutz.dao.impl.NutDao;
import org.nutz.dao.sql.Criteria;
import org.nutz.dao.sql.Sql;

import com.ibatis.sqlmap.client.SqlMapClient;
import com.ibatis.sqlmap.client.SqlMapClientBuilder;
import com.jxt.app.controller.MessageController;
import com.jxt.app.dao.ApmessagesDAOImpl;
import com.jxt.app.entity.Apiphone;
import com.jxt.app.entity.ApiphoneExample;
import com.jxt.app.entity.Apmessages;
import com.jxt.app.entity.ApmessagesExample;
import com.jxt.app.entity.Apmsgmember;
import com.jxt.app.entity.Messages;
import com.jxt.app.entity.Resources;
import com.jxt.app.service.impl.ApMessageServiceImpl;
import com.jxt.app.service.impl.ApiphoneServiceImpl;
import com.jxt.app.vo.ApmessagesVo;
import com.jxt.system.util.SqlServerDataSourceManager;

import javapns.back.PushNotificationManager;
import javapns.back.SSLConnectionHelper;
import javapns.data.Device;
import javapns.data.PayLoad;
import javapns.exceptions.NullIdException;
import javapns.exceptions.UnknownDeviceException;

public class MainApnsSend
{
	// 日志记录器
	private static final Logger logger = Logger.getLogger(MainApnsSend.class);

	static PushNotificationManager pushManager = PushNotificationManager.getInstance();
	private static List<Apiphone> apiphoneList=new ArrayList<Apiphone>();
	
	
	
	private static List<Messages> messageList=new ArrayList<Messages>();
	private static HashMap<String,List<Messages>> cacheMessage=new  HashMap<String,List<Messages>>();
		
	public  static HashMap<String,Apiphone> apIphoneUser=new HashMap<String,Apiphone>();
	public static HashMap<String, List<ApmessagesVo>> cacheApMessages=new  HashMap<String,List<ApmessagesVo>>();
	private static String certificationPath="";
	
	private static SqlMapClient sqlMapClient = null;
	private Dao dao;
	public MainApnsSend(){
		//读取配置文件
		InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("push.properties");
		Properties p = new Properties();
		try{
			p.load(inputStream);
		}catch(IOException e1) {
			e1.printStackTrace();
		}
		certificationPath=p.getProperty("Certification");
		if(certificationPath!=null){
//			try {
//				//certificationPath = new String(certificationPath.getBytes("ISO-8859-1"),"gbk");
//			} catch (UnsupportedEncodingException e) {
//				// TODO Auto-generated catch block
//				e.printStackTrace();
//			}
		}
		System.out.println("ip:"+p.getProperty("Certification")+",port:"+p.getProperty("port")); 
		DataSource ds = SqlServerDataSourceManager.INSTANCE.getDataSource();
		dao = new NutDao(ds);

	   // Apiphone apiphone=new Apiphone();
	   // apiphone.setDtoken("c60b33344dc727bff137bbddb0216fcce9579c48de4873845d094f0e47134275");
		
	   List<Apiphone> initApiphoneList=dao.query(Apiphone.class, null, null);//初始化推送用户表 
	   
	   for(Apiphone apiphone:initApiphoneList){   
		   apIphoneUser.put(apiphone.getUserid(), apiphone);
	   }
	   

	 	String sqlStr = "select a.*,b.*,b.id as msgids from apmessages a left join  apmsgmember b on a.id=b.msgid   where  b.ispush=0 and b.isread=0";
		Sql sql = Sqls.create(sqlStr);
		sql.setCallback(Sqls.callback.entities());
		Entity<Messages> msgEntity = dao.getEntity(Messages.class);
		sql.setEntity(msgEntity);
		dao.execute(sql);
		
		List<Messages>  mesList=sql.getList(Messages.class);
		for(Messages record:mesList){
			String key=record.getReceiveid();
			
			ApmessagesVo  apmsgVo=new ApmessagesVo();
			apmsgVo.setCanReply(record.getCanReply());
			apmsgVo.setDialogid(record.getDialogid());
			apmsgVo.setFilename(record.getFilename());
			apmsgVo.setFileurl(record.getFileurl());
			apmsgVo.setId(record.getId());
			apmsgVo.setInfotype(record.getInfotype());
			apmsgVo.setIschecked(record.getIschecked());
			apmsgVo.setMsg(record.getMsg());
			apmsgVo.setSendTime(record.getSendTime());
			apmsgVo.setSendid(record.getSendid());
			apmsgVo.setSendname(record.getSendname());
			apmsgVo.setSendtype(record.getSendtype());
			apmsgVo.setIsread(record.getIsread());
			if(cacheApMessages.containsKey(key)){
					if(null==cacheApMessages.get(key)){
						List<ApmessagesVo> myList=new ArrayList<ApmessagesVo>();
						myList.add(apmsgVo);
						cacheApMessages.put(key, myList);
					}else{
						List<ApmessagesVo> myList=cacheApMessages.get(key);
						myList.add(apmsgVo);
						cacheApMessages.put(key, myList);
					}

			}else{
				List<ApmessagesVo> myList=new ArrayList<ApmessagesVo>();
				myList.add(apmsgVo);
				cacheApMessages.put(key, myList);
				
			}
			logger.debug( "消息 初始化装配…… " );
		}
	   
	   
		//Timer timer = new Timer();
	       // timer.schedule(new MainApnsSend().new MsgTimerTask(), 0,5000 );
			//sendCommerceAPNS("sendCommerceAPNS");
	    
	}
	public static void main(String[] args) throws Exception
	{	
		
	
		Timer timer = new Timer();
	    timer.schedule(new MainApnsSend().new MsgTimerTask(), 0,5000 );
	   // timer.schedule(new MainApnsSend().new MessageLoadTimerTask(), 0,5000 );
		//sendCommerceAPNS("sendCommerceAPNS");
		//sendCommerceAPNS("");
	}
	public  static void Autorun(){
		Timer timer = new Timer();
	    timer.schedule(new MainApnsSend().new MsgTimerTask(), 0,5000 );

	}
	
	public  static void MsgClearTimerTaskAutorun(){
		Timer timer = new Timer();
	    timer.schedule(new MainApnsSend().new MsgClearTimerTask(), 0,1000*3600*2 );//每2小时清理下过时推送信息
		
	}
	public  static void ResTimerTaskTaskAutorun(){
		Timer timer = new Timer();
		timer.schedule(new MainApnsSend().new ResTimerTask(), 0,55000 );//课件推送定时
		
	}
	
	public  static void UserOnlineCheck(){
		Timer timer = new Timer();
	    timer.schedule(new MainApnsSend().new UserOnlineTimerTask(), 0,5*60*1000 );
	   // timer.schedule(new MainApnsSend().new MessageLoadTimerTask(), 0,5000 );
		//sendCommerceAPNS("sendCommerceAPNS");
		
	}
	
	
	
	
	/**
	 *  用户上下线状态判断
	 * @author pp
	 *
	 */
	public class UserOnlineTimerTask extends TimerTask {

		
        @Override
	     public void run() {
        	
        	
			     try{
			    	// String result = HTTPUtil.getHttpResult("http://192.168.1.101:8080/jxt/app/msg/list/88468/1/5.json","");
			    	 Iterator iterator = apIphoneUser.keySet().iterator();
			    	 while(iterator.hasNext()) {
			    		// System.out.println(apIphoneUser.get(iterator.next()));
			    		Object key=iterator.next();
			    		Apiphone apiphone=apIphoneUser.get(key);
			    		if(null!=apiphone.getLastvist()){		
			    			long datetime=new Date().getTime()-apiphone.getLastvist().getTime();
			    			long compareTime=2*60*1000;//2分钟未访问立即下线 
			    			
			    			logger.debug(datetime-compareTime);
			    			
			    			if(datetime>compareTime){
			    				apiphone.setIsonline((byte)0);
			    			}else{			    				
			    				apiphone.setIsonline((byte)1);//设置为上线 
			    			}	
			    		}else{
			    			apiphone.setIsonline((byte)0);
			    		}
			    		
			    		
			    		 logger.debug(apiphone.getUserid()+"===>>>>"+apiphone.getIsonline());
			    		 Sql sql = Sqls.create("UPDATE apiphone SET isonline=@isonline where $condition");

			    		 sql.params().set("isonline", apiphone.getIsonline());

			    		 sql.setCondition(Cnd.wrap("dtoken='"+apiphone.getDtoken()+"'"));

			    		 dao.execute(sql);
			    		
			    	 } 
			    	 
	
			    	 logger.debug("用户在线检测..."); 
			    	 
			     }catch(Exception e){
			    	 logger.debug(e);
			     }
		   }
	
	
	}
	
	
	
	
	
	
	/**
	 * 更新消息缓存
	 * @param record
	 * @param apmsgmemberList
	 */
	public static void updateCacheMessage(Apmessages record,List<Apmsgmember> apmsgmemberList){
		
		for(Apmsgmember apmsgmember: apmsgmemberList){
			String key=apmsgmember.getReceiveid();
			ApmessagesVo  apmsgVo=new ApmessagesVo();
			apmsgVo.setCanReply(record.getCanReply());
			apmsgVo.setDialogid(record.getDialogid());
			apmsgVo.setFilename(record.getFilename());
			apmsgVo.setFileurl(record.getFileurl());
			apmsgVo.setId(record.getId());
			apmsgVo.setInfotype(record.getInfotype());
			apmsgVo.setIschecked(record.getIschecked());
			apmsgVo.setMsg(record.getMsg());
			apmsgVo.setSendTime(record.getSendTime());
			apmsgVo.setSendid(apmsgmember.getSendid());
			apmsgVo.setSendname(apmsgmember.getSendname());
			apmsgVo.setSendtype(apmsgmember.getSendtype());
			apmsgVo.setIsread(apmsgmember.getIsread());
			
			Apiphone apiphone=apIphoneUser.get(key);
			if(apiphone!=null){
				if(apiphone.getIsonline()==0){//不在线，即推送
					if(apmsgVo.getInfotype()==1){
    					sendCommerceAPNS(apiphone.getDtoken(),"你有一条图片消息！",null,null);
    				}else if(apmsgVo.getInfotype()==2){
    					sendCommerceAPNS(apiphone.getDtoken(),"你有一条语音消息！",null,null);
    				
    				}else{	
    					sendCommerceAPNS(apiphone.getDtoken(),apmsgVo.getMsg(),null,null);
    					
    				}
				}
				
			}
			
			if(cacheApMessages.containsKey(key)){
			
					if(null==cacheApMessages.get(key)){
						List<ApmessagesVo> myList=new ArrayList<ApmessagesVo>();
						myList.add(apmsgVo);
						cacheApMessages.put(key, myList);
					}else{
						List<ApmessagesVo> myList=cacheApMessages.get(key);
						myList.add(apmsgVo);
						cacheApMessages.put(key, myList);
					}

			}else{
				
				List<ApmessagesVo> myList=new ArrayList<ApmessagesVo>();
				myList.add(apmsgVo);
				cacheApMessages.put(key, myList);
				
			}
			
		}
	
	}
	
	
	
	
			    

	/**
	 * 定时消息清理轮询
	 * @author pp
	 *
	 */
	public class MsgClearTimerTask extends TimerTask {
		 
        @Override
	     public void run() {
        	
        	
			     try{   	
				        //时间间隔大于1天的消息
			 			String sqlStr = "select a.*,b.*,b.id as msgids from apmessages a left join  apmsgmember b on a.id=b.msgid    where datediff(hour,a.send_time,getdate())>24 and b.ispush=0 and b.isread=0";
			    		Sql sql = Sqls.create(sqlStr);
			    		sql.setCallback(Sqls.callback.entities());
			    		Entity<Messages> msgEntity = dao.getEntity(Messages.class);
			    		sql.setEntity(msgEntity);
			    		dao.execute(sql);
			    		
			    		List<Messages> mesgList=sql.getList(Messages.class);
			        		//System.out.print(mesgList);
			        		if(null!=mesgList){
			        			for(Messages msg:mesgList){ 
			        						String updateSql="update apmsgmember set ispush=1 where id='";//大于24小时取消推送
			        						updateSql+=(msg.getMsgid()+"'");
			        						Sql sqlS = Sqls.create(updateSql);
					        				
					        				dao.execute(sqlS);
					        				
					        				//System.out.println(msg.getDtoken());
					        			
			        				
			        			}
			        		}
			        		
			        		//logger.debug( " 消息轮询…… " );
			     }catch(Exception e){
			    	 
			    	 logger.debug(e);
			     }
	        }
	
	}
	
	
	
	
	/**
	 * 定时课件推送轮询
	 * @author pp
	 *
	 */
	public class ResTimerTask extends TimerTask {
		 
        @Override
	     public void run() {
        	
        	
			     try{   	
				        //查询用户不在线的才推送出去
			 			String sqlStr = "select a.*,b.*,b.id as msgids from apresource a left join  apresmember b on a.id=b.resid right join apiphone c  on c.userid=b.receiveid  where c.isonline=0 and  b.ispush=0 and b.isread=0";
			    		Sql sql = Sqls.create(sqlStr);
			    		sql.setCallback(Sqls.callback.entities());
			    		Entity<Resources> msgEntity = dao.getEntity(Resources.class);
			    		sql.setEntity(msgEntity);
			    		dao.execute(sql);
			    		
			    		List<Resources> mesgList=sql.getList(Resources.class);
			        		//System.out.print(mesgList);
			        		if(null!=mesgList){
			        			for(Resources msg:mesgList){ 
			        				
			        					if(null!=msg.getDtoken()){//是IPHONE用户
			        						String updateSql="update apresmember set ispush=1 where id='";
			        						updateSql+=(msg.getMsgid()+"'");
			        						Sql sqlS = Sqls.create(updateSql);
					        				//这里调用推送接口
					        				if(msg.getType()==1){///1听写英语/2优展示/3同步解析/4易错题库
					        					sendCommerceAPNS(msg.getDtoken(),"你有一条听写英语消息！",null,null);
					        				}else if(msg.getType()==2){
					        					sendCommerceAPNS(msg.getDtoken(),"你有一条优展示消息！",null,null);
					        				
					        				}else if(msg.getType()==3){
					        					sendCommerceAPNS(msg.getDtoken(),"你有一条同步解析消息！",null,null);
					        				
					        				}else if(msg.getType()==4){
					        					sendCommerceAPNS(msg.getDtoken(),"你有一条易错题库消息！",null,null);
					        				
					        				}else{	
					        					sendCommerceAPNS(msg.getDtoken(),msg.getTitle(),null,null);
					        					
					        				}
					        				dao.execute(sqlS);
					        				
					        				System.out.println(msg.getDtoken());
					        				//updatSql
			        					}else{//不是IPHONE 用户或者未使用APP，将其消息设置为已推送且已阅读
			        						
			        					
			        						
			        					}
			        				
			        			}
			        		}
			        		
			        		logger.debug( " 课件轮询…… "+mesgList.size() );
			     }catch(Exception e){
			    	 
			    	 logger.debug(e);
			     }
	        }
	
	}
	
	
	
	
	
	
	/**
	 * 定时消息推送轮询
	 * @author pp
	 *
	 */
	public class MsgTimerTask extends TimerTask {
		 
        @Override
	     public void run() {
        	
        	
			     try{   	
				        //查询用户不在线的才推送出去
			 			String sqlStr = "select a.*,b.*,b.id as msgids from apmessages a left join  apmsgmember b on a.id=b.msgid right join apiphone c  on c.userid=b.receiveid  where datediff(hour,a.send_time,getdate())<24 and c.isonline=0 and  b.ispush=0 and b.isread=0";
			    		Sql sql = Sqls.create(sqlStr);
			    		sql.setCallback(Sqls.callback.entities());
			    		Entity<Messages> msgEntity = dao.getEntity(Messages.class);
			    		sql.setEntity(msgEntity);
			    		dao.execute(sql);
			    		
			    		List<Messages> mesgList=sql.getList(Messages.class);
			        		//System.out.print(mesgList);
			        		if(null!=mesgList){
			        			for(Messages msg:mesgList){ 
			        				
			        					if(null!=msg.getDtoken()){//是IPHONE用户
			        						String updateSql="update apmsgmember set ispush=1 where id='";
			        						updateSql+=(msg.getMsgid()+"'");
			        						Sql sqlS = Sqls.create(updateSql);
					        				//这里调用推送接口
					        				if(msg.getInfotype()==1){
					        					sendCommerceAPNS(msg.getDtoken(),"你有一条图片消息！",null,null);
					        				}else if(msg.getInfotype()==2){
					        					sendCommerceAPNS(msg.getDtoken(),"你有一条语音消息！",null,null);
					        				
					        				}else{	
					        					sendCommerceAPNS(msg.getDtoken(),msg.getMsg(),null,null);
					        					
					        				}
					        				dao.execute(sqlS);
					        				
					        				System.out.println(msg.getDtoken());
					        				//updatSql
			        					}else{//不是IPHONE 用户或者未使用APP，将其消息设置为已推送且已阅读
			        						
			        					
			        						
			        					}
			        				
			        			}
			        		}
			        		
			        		logger.debug( " 消息轮询…… " +mesgList.size());
			     }catch(Exception e){
			    	 
			    	 logger.debug(e);
			     }
	        }
	
	}
	
	
	public  static void sendCommerceAPNSByIdList(String idList,String alert,String badge,String sound)
	{
		try
		{
			
			
			if(null!=idList){
				String[] idArray=idList.split(","); 
				if(null!=idArray){
					
					for(int i=0;i<idArray.length;i++){
    					for(Apiphone apiphone:apiphoneList){
    						if(apiphone.getUserid().equals(idArray[i])){
    							String token=apiphone.getDtoken();
    							sendCommerceAPNS(token,alert,"1","");
    						}
    					}
    				}
				}
			}


		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
	}
	
	
	
	/**
	 * 消息方法推送封装
	 * @param token
	 * @param alert
	 * @param badge
	 * @param sound
	 */
	public static  void sendCommerceAPNS(String token,String alert,String badge,String sound)
	{
		try
		{
			if(token==null)
			return;
			logger.debug("进入消息推送==>>"+token);
			//String deviceToken = "c60b33344dc727bff137bbddb0216fcce9579c48de4873845d094f0e47134275";//iphone手机获取的token
			PayLoad payLoad = new PayLoad();
			payLoad.addAlert(alert);//push的内容
			payLoad.addBadge(1);//图标小红圈的数值
			//payLoad.addSound("default");//铃音
			
			pushManager.addDevice(token, token);
			//Connect to APNs
			/***********************************************************************************************************
			 * 测试的服务器地址：gateway.sandbox.push.apple.com /端口2195 产品推送服务器地址：gateway.push.apple.com / 2195
			 **********************************************************************************************************/
			String host = "gateway.sandbox.push.apple.com";
			int port = 2195;
			String certificatePath = certificationPath;//导出的证书
			String certificatePassword = "123";//此处注意导出的证书密码不能为空因为空密码会报错
			pushManager.initializeConnection(host, port, certificatePath, certificatePassword, SSLConnectionHelper.KEYSTORE_TYPE_PKCS12);
			//Send Push
			Device client = null;
			if(client==null){
				client = pushManager.getDevice(token);
			}
			pushManager.sendNotification(client, payLoad);
			pushManager.stopConnection();
			pushManager.removeDevice(token);
		}
		catch (Exception e)
		{
			try {
				pushManager.removeDevice(token);
			} catch (UnknownDeviceException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			} catch (NullIdException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
			e.printStackTrace();
		}
	}
	
	
	//暂时无用方法 
	public static void sendCommerceAPNS(String token)
	{
		try
		{
			String deviceToken = "7e7f337a9947176f387e27b2b75be3846307e7b1ec6fdddbd2894ddffe42d55d";//iphone手机获取的token
			PayLoad payLoad = new PayLoad();
			payLoad.addAlert("我的push测试");//push的内容
			payLoad.addBadge(99);//图标小红圈的数值
			//payLoad.addSound("default");//铃音
			PushNotificationManager pushManager = PushNotificationManager.getInstance();
			pushManager.addDevice("iPhone", deviceToken);
			//Connect to APNs
			/***********************************************************************************************************
			 * 测试的服务器地址：gateway.sandbox.push.apple.com /端口2195 产品推送服务器地址：gateway.push.apple.com / 2195
			 **********************************************************************************************************/
			String host = "gateway.sandbox.push.apple.com";
			int port = 2195;
			String certificatePath = certificationPath;//导出的证书
			String certificatePassword = "123";//此处注意导出的证书密码不能为空因为空密码会报错
			pushManager.initializeConnection(host, port, certificatePath, certificatePassword, SSLConnectionHelper.KEYSTORE_TYPE_PKCS12);
			//Send Push
			Device client = pushManager.getDevice("iPhone");
			pushManager.sendNotification(client, payLoad);
			pushManager.stopConnection();
			pushManager.removeDevice("iPhone");
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
	}


}